package server;

import game.GameInstance;
import game.Player;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import server.net.Client;

/**
 * This class keeps a record of all the available players.
 * 
 * @author nathanposlusny
 * @author Vincent Tsuei
 * @version 2012-11-20
 */
public class PlayerRegistry {
    
    private GameServer server;
    private HashMap<String,Player> availPlayers;
    private final ReentrantReadWriteLock newLock = new ReentrantReadWriteLock();
    
    public PlayerRegistry(GameServer server) {
        this.server = server;
        this.availPlayers = new HashMap<String, Player>();   
    }
   
    /**
     * Adds player to availPlayer hashmap
     * 
     * @param playerName
     * @return Returns a reference to a new Player if the player
     * can be added with the specified ID, and returns null otherwise.
     */
    public Player addPlayer(String playerName, Client client) {
        
        Player p = null;
        newLock.writeLock().lock();
        try {
            if (!(availPlayers.containsKey(playerName))) {
                p = new Player(playerName, client);
                availPlayers.put(playerName, p);
            }
            else return null;
        }
        finally {
            newLock.writeLock().unlock();
            return p;
        }
    }
    
    /**
     * Remove this player from the registry.
     */
    public void removePlayer(Player p) {
        removePlayer(p.getName());
    }

    /**
     * Remove the player with the specified ID from the registry.
     */
    public void removePlayer(String playerID) {
        newLock.writeLock().lock();
        try {
            availPlayers.remove(playerID);
        }
        finally {
            newLock.writeLock().unlock();
        }    
    }
    
    /**
     * Return all available players
     * 
     */
    private static final Player[] getAllPlayersArr = new Player[0];
    public Player[] getAllPlayers() {
        newLock.readLock().lock();
        try {
            return availPlayers.values().toArray(getAllPlayersArr);
        } finally {
            newLock.readLock().unlock();
        }
    }
    
    /**
     * Returns whether this player is on the server.
     */
    public boolean containsPlayer(String pName) {
        newLock.readLock().lock();
        try {
            return availPlayers.containsKey(pName);
        } finally {
            newLock.readLock().unlock();
        }
    }
    
    /**
     * Returns the player with the specified name.
     */
    public Player getPlayer(String pName) {
        newLock.readLock().lock();
        try {
            return availPlayers.get(pName);
        } finally {
            newLock.readLock().unlock();
        }
    }
}


